package com.ylp.sys.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ylp.common.exception.ServiceException;
import com.ylp.common.response.PageResult;
import com.ylp.common.response.Result;
import com.ylp.common.utils.StringUtils;
import com.ylp.sys.auth.entity.UserInfo;
import com.ylp.sys.auth.utils.BCryptUtils;
import com.ylp.sys.domain.dto.ResetPass;
import com.ylp.sys.domain.dto.UserDto;
import com.ylp.sys.domain.dto.UserPageDto;
import com.ylp.sys.domain.entity.SysUser;
import com.ylp.sys.domain.entity.SysUserRole;
import com.ylp.sys.domain.vo.UserVo;
import com.ylp.sys.mapper.SysUserMapper;
import com.ylp.sys.mapper.SysUserRoleMapper;
import com.ylp.sys.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 *
 * @author cc
 * @since 2024-07-24
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final SysUserMapper userMapper;
    private final SysUserRoleMapper userRoleMapper;

    public  SysUserServiceImpl(SysUserMapper userMapper, SysUserRoleMapper userRoleMapper) {
        this.userMapper = userMapper;
        this.userRoleMapper = userRoleMapper;
    }

    /**
     * 获取当前用户信息
     * @param id
     * @return
     */
    @Override
    public Result<SysUser> getUserById(Long id) {
        SysUser user = null;
        try {
            user = userMapper.selectById(id);
        } catch (Exception e) {
            throw new ServiceException("获取当前用户信息失败");
        }
        return Result.success(user);
    }

    /**
     * 分页查询
     * @param userPageDto
     * @return
     */
    @Override
    public PageResult<SysUser> pageList(UserPageDto userPageDto) {
        IPage<SysUser> page = null;
        // like 条件构造
        try {
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.like(StringUtils.isNotEmpty(userPageDto.getUsername()), SysUser::getUsername, userPageDto.getUsername())
                    .like(StringUtils.isNotEmpty(userPageDto.getMobile()), SysUser::getMobile, userPageDto.getMobile());
            if (userPageDto.getStatus() != -1) {
                wrapper.eq(SysUser::getStatus, userPageDto.getStatus());
            }
            // 分页构造
            page = new Page<>(userPageDto.getCurrentPage(), userPageDto.getPageSize());
            userMapper.selectPage(page, wrapper);
        } catch (Exception e) {
            throw new ServiceException("查询失败");
        }
        return new PageResult<SysUser>(page.getRecords(), page.getTotal());
    }

    /**
     * 根据id 删除
     * @param ids
     */
    @Transactional
    @Override
    public void deleteUserByIds(List<Long> ids) {
        userMapper.deleteBatchIds(ids);
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SysUserRole::getUserId, ids);
        userRoleMapper.delete(wrapper);
    }

    /**
     * 添加用户
     * @param userDto
     * @return
     */
    @Transactional
    @Override
    public int addUser(UserDto userDto) {
        int result = 0;
        UserInfo userLoginInfo = (UserInfo) StpUtil.getSession().get("userInfo");
        String userName = userLoginInfo.getUsername();
        SysUser user = new SysUser();
        BeanUtil.copyProperties(userDto, user);
        user.setCreator(userName);
        user.setUpdater(userName);
        user.setDeleted((byte)0);
//            user.setStatus(0);
        String password = BCryptUtils.encode(userDto.getPassword());
        user.setPassword(password);
        userMapper.insert(user);
        Long userId = user.getId();
        for (Long roleId: userDto.getRoleIds()) {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleMapper.insert(userRole);
        }
        result = 1;
        return result;
    }

    /**
     * 获取用户和角色ids
     * @param id
     * @return
     */
    @Override
    public UserVo getUserAndIdsById(Long id) {
        UserVo userVo = new UserVo();
        try {
            SysUser user = userMapper.selectById(id);
            BeanUtil.copyProperties(user, userVo);
            LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUserRole::getUserId, user.getId());
            List<SysUserRole> userRoles = userRoleMapper.selectList(wrapper);
            List<Long> roleIds = userRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
            List<Long> selecectRoleIds = roleIds.stream().distinct().collect(Collectors.toList());
            userVo.setRoleIds(selecectRoleIds);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException();
        }
        return userVo;
    }

    /**
     * 修改用户和角色信息
     * @param userDto
     */
    @Transactional
    @Override
    public void updateAndRoles(UserDto userDto) {
        // 更新用户
        UserInfo userLoginInfo = (UserInfo) StpUtil.getSession().get("userInfo");
        String userName = userLoginInfo.getUsername();
        SysUser user = new SysUser();
        BeanUtil.copyProperties(userDto, user);
        user.setUpdater(userName);
        userMapper.updateById(user);
        if (userDto.getRoleIds() != null && userDto.getRoleIds().size() > 0) {
            // 删除原来角色关联
            LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUserRole::getUserId, user.getId());
            userRoleMapper.delete(wrapper);
            // 更新角色关联
            Long userId = user.getId();
            for (Long roleId: userDto.getRoleIds()) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                userRoleMapper.insert(userRole);
            }
        }
    }

    /**
     * 重置密码
     * @param resetPass
     * @return
     */
    @Override
    public int resetPass(ResetPass resetPass) {
        int result = 0;
        try {
            LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<>();
            String password = BCryptUtils.encode(resetPass.getPassword());
            wrapper.set(SysUser::getPassword, password);
            wrapper.eq(SysUser::getId, resetPass.getId());
            result = userMapper.update(wrapper);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("重置失败");
        }
        return result;
    }

    @Override
    public void updateStatus(SysUser user) {
        try {
            LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<>();
            wrapper.set(SysUser::getStatus, user.getStatus());
            wrapper.eq(SysUser::getId, user.getId());
            userMapper.update(wrapper);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("修改失败");
        }
    }
}
